#ifndef NIGHTVISION
#define NIGHTVISION
#include "aa.h"
#include "blur.h"
float2 noise = float2(.5f/1024.f,.5f/768.f);

float  zoom(float input, float factor, float offset) { return (input-0.5f+offset) / factor+0.5f-offset; }
float2 zoom2(float2 input, float factor, float2 offsetXY) { return float2(zoom(input.x, factor, offsetXY.x), zoom(input.y, factor, offsetXY.y)); }
float4 zoom4(float4 input, float factor, float2 offsetXY) { float4 result; result.xy = zoom2(input.xy, factor, offsetXY); result.z=input.z; result.w=input.w; return result; }
v2p zoom_v2p(v2p input, float factor, float2 offsetXY)
{
	v2p result;
	result.tc0 = zoom4(input.tc0, factor, offsetXY);
	result.tc1 = zoom4(input.tc1, factor, offsetXY);
	result.tc2 = zoom4(input.tc2, factor, offsetXY);
	result.tc3 = zoom4(input.tc3, factor, offsetXY);
	result.tc4 = zoom4(input.tc4, factor, offsetXY);
	result.tc5 = zoom4(input.tc5, factor, offsetXY);
	result.tc6 = zoom4(input.tc6, factor, offsetXY);
	return result;
}

half4 nv( v2p In, half4 color, float3 visionColor, bool entireScreen) : COLOR
{
  // Settings  
  float brightness = NV_BRIGHTNESS;
  
  float2 measurePoints[9];
  measurePoints[0] = float2(0.50001f, 0.50001f);
  measurePoints[1] = float2(0.40001f, 0.50001f);
  measurePoints[2] = float2(0.60001f, 0.50001f);
  measurePoints[3] = float2(0.50001f, 0.40001f);
  measurePoints[4] = float2(0.50001f, 0.60001f);
  measurePoints[5] = float2(0.40001f, 0.40001f);
  measurePoints[6] = float2(0.40001f, 0.60001f);
  measurePoints[7] = float2(0.60001f, 0.40001f);
  measurePoints[8] = float2(0.60001f, 0.60001f);
	
  half4 finalColor;
  
  bool returnNow = false;
  
  float px=In.tc0.x-0.5f;
  float py=(In.tc0.y-0.5f) * NV_SCREENRATIO;	// correction for 4:3 / 16:10 ratio
  float center_dist = sqrt(pow(px, 2) + pow(py, 2));	// absolute distance from screen center	
  
  if (entireScreen || center_dist < NV_RADIUS)
  {	
	// Use magnification
	#ifdef NV_ZOOM	
	float bias = saturate(center_dist/NV_RADIUS);
	float zoom = NV_ZOOM+bias*NV_BIAS; // effective zoom level for current pixel
	float4 newpos = In.tc0;
	if (!entireScreen) newpos = In.tc0 = zoom4(In.tc0, zoom, 0);	
	#else
	float4 newpos = In.tc0;
	#endif	
	
	float m = tex2D(s_image, newpos).r;	
	float redFactor = (1-NV_RED + m * NV_RED);
	
	float3 c=tex2D(s_image,newpos).rgb;	
	
	// measure and compute center luminance
	float totalLum = 0;
	float pitch_diff = 4.4;  
	for (int i=0; i < 9; i++)
	{
		float3 pointRgb = tex2D(s_image, measurePoints[i]).rgb;		// color at measure point
		float pointLum = (pointRgb.x + pointRgb.y + pointRgb.z) / 3.f;	// luminance at measure point
		totalLum += pointLum;
		
		// Show measure points on screen		
		float pitch_x = abs(In.tc0.x - measurePoints[i].x);
		float pitch_y = abs(In.tc0.y - measurePoints[i].y);
		if (pitch_x < pitch_diff && pitch_y < pitch_y)
		{
			finalColor.rgb = float3(1.0, 0.0, 1.0);
			returnNow = true;
		}
	}	
	
	if (!returnNow)
	{	
		float avgLum = totalLum/9.f;	// average luminance				
		brightness /= avgLum;		
		if (brightness < NV_MINBRIGHT) brightness = NV_MINBRIGHT;		
		else if (brightness > NV_MAXBRIGHT) brightness = NV_MAXBRIGHT;		

		float lum = dot(float3(0.30, 0.59, 0.11), c);		
		c *= NV_AMP * (1.f-lum);
		
		// Apply vision color and adjustments (only if not "white" which means no color)		
		if (visionColor.x+visionColor.y+visionColor.z != 3)
		{
			// set nightvision color
			finalColor.rgb = c * visionColor * redFactor;		
		
			// set contrast
			finalColor.rgb = (1 - NV_CONTRAST) + finalColor.rgb * NV_CONTRAST;
		
			// set brightness (limited!)
			float endLum = (finalColor.rgb.x + finalColor.rgb.y + finalColor.rgb.z) / 3.f;
			if (endLum * brightness > NV_MINBRIGHT)
				brightness = NV_MINBRIGHT / endLum;
			finalColor.rgb *=  brightness;
		}
		else		
			finalColor.rgb = tex2D(s_image,newpos).rgb;
	}
   }
   else
   {
		finalColor = color;
   }  
  
  finalColor.a = 1.0;
  return finalColor;
}
#endif